##
## project definition
##
#project('spice-gtk', 'c',
#         version : run_command('build-aux/git-version-gen', '@0@/.tarball-version'.format(meson.project_source_root()), check : true).stdout().strip(),
#         license : 'LGPLv2.1',
#         meson_version : '>= 0.56',
#         default_options : ['buildtype=debugoptimized',
#                            'warning_level=2'])
cmake_minimum_required(VERSION 3.21)
project(spice-gtk)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(my_utils)

# option(alignment-checks "Enable runtime checks for cast alignment" OFF)
option(gtk "Enable gtk+" OFF)
option(ENABLE_GSTREAMER_MOBILE_DEPS "enable GStreamer::mobile?" OFF)
my_multi_option(coroutine "gthread" "Use ucontext or GThread for coroutines" ucontext libucontext gthread winfiber)


set(CMAKE_POSITION_INDEPENDENT_CODE ON)

find_package(PkgConfig)
pkg_check_modules(SPICE_PROTOCOL IMPORTED_TARGET spice-protocol)
if (NOT ENABLE_GSTREAMER_MOBILE_DEPS)
pkg_check_modules(GLIB IMPORTED_TARGET glib-2.0)
pkg_check_modules(PIXMAN IMPORTED_TARGET pixman-1)
pkg_check_modules(JSON_GLIB IMPORTED_TARGET json-glib-1.0)
pkg_check_modules(SSL IMPORTED_TARGET libssl)
pkg_check_modules(CRYPT IMPORTED_TARGET libcrypt)
pkg_check_modules(JPEG IMPORTED_TARGET libjpeg)
pkg_check_modules(OPUS IMPORTED_TARGET opus)
pkg_check_modules(GSTREAMER IMPORTED_TARGET gstreamer-1.0)
pkg_check_modules(GSTREAMER_BASE IMPORTED_TARGET gstreamer-base-1.0)
pkg_check_modules(GSTREAMER_APP IMPORTED_TARGET gstreamer-app-1.0)
pkg_check_modules(GSTREAMER_AUDIO IMPORTED_TARGET gstreamer-video-1.0)
pkg_check_modules(GSTREAMER_VIDEO IMPORTED_TARGET gstreamer-audio-1.0)
pkg_check_modules(ZLIB IMPORTED_TARGET zlib)
endif()
if (gtk)
pkg_check_modules(GTK IMPORTED_TARGET gtk+-3.0)
endif()


#
#meson.add_dist_script('build-aux/meson-dist', meson.project_version(), meson.project_source_root())
#summary_info = {}
#
##
## global C defines
##
#summary_info = {'prefix': get_option('prefix')}
#spice_gtk_prefix = get_option('prefix')
#spice_gtk_bindir = spice_gtk_prefix / get_option('bindir')
#spice_gtk_datadir = spice_gtk_prefix / get_option('datadir')
#spice_gtk_localedir = spice_gtk_datadir / 'locale'
#spice_gtk_includedir = spice_gtk_prefix / get_option('includedir')
#spice_gtk_global_cflags = ['-DHAVE_CONFIG_H',
#                           '-DSPICE_COMPILATION',
#                           '-DG_LOG_DOMAIN="GSpice"',
#                           '-Wno-sign-compare',
#                           '-Wno-unused-parameter',
#                           '-Wno-cast-function-type']
set(spice_gtk_global_flags
        "-DHAVE_CONFIG_H"
        "-DSPICE_COMPILATION"
        "-DG_LOG_DOMAIN=\"GSpice\""
        "-Wno-sign-compare"
        "-Wno-unused-parameter"
        "-Wno-cast-function-type"
)

#
## other global vars
#compiler = meson.get_compiler('c')
#spice_gtk_config_data = configuration_data()
#spice_gtk_include = [include_directories('.')]
set(spice_gtk_include ${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND spice_gtk_include ${CMAKE_CURRENT_BINARY_DIR})
#spice_glib_deps = []
#spice_gtk_deps = []
#spice_wayland_deps = []
#spice_acl_deps = []
#spice_protocol_version = '0.14.3'

set(spice_protocol_version "0.14.3")
#
##
## Set up subprojects
##
#spice_common = subproject('spice-common',
#                          default_options : [
#                            'generate-code=client',
#                            'spice-protocol-version=@0@'.format(spice_protocol_version),
#                          ])
add_subdirectory(subprojects/spice-common)

#spice_gtk_config_data.merge_from(spice_common.get_variable('spice_common_config_data'))
#spice_glib_deps += spice_common.get_variable('spice_common_client_dep')
#spice_protocol_version = spice_common.get_variable('spice_protocol_version')
#
#keycodemapdb = subproject('keycodemapdb')
#
#keymapgen = find_program('keymap-gen')
#keymapcsv = keycodemapdb.get_variable('keymaps_csv')
#
##
## check for system headers
##
#headers = [
#  'termios.h',
#  'X11/XKBlib.h',
#  'sys/socket.h',
#  'sys/types.h',
#  'netinet/in.h',
#  'arpa/inet.h',
#  'valgrind/valgrind.h',
#  'sys/disk.h'
#]
#
#foreach header : headers
#  if compiler.has_header(header)
#    spice_gtk_config_data.set('HAVE_@0@'.format(header.underscorify().to_upper()), '1')
#  endif
#endforeach
#
#spice_gtk_has_egl = compiler.has_header('epoxy/egl.h', required: get_option('egl'))
#spice_gtk_config_data.set('HAVE_EGL', spice_gtk_has_egl)
#
##
## check for system functions
##
#foreach func : ['clearenv', 'strtok_r']
#  if compiler.has_function(func)
#    spice_gtk_config_data.set('HAVE_@0@'.format(func.underscorify().to_upper()), '1')
#  endif
#endforeach
check_function_exists(clearenv have_clearenv)
if (have_clearenv)
    set(HAVE_CLEARENV 1) #for config.h
endif()
check_function_exists(strtok_r have_strtok_r)
if (have_strtok_r)
    set(HAVE_STRTOK_R 1) #for config.h
endif()
#
##
## check for mandatory dependencies
##
#glib_version = '2.52'
#glib_version_info = '>= @0@'.format(glib_version)
#pixman_version = '>= 0.17.7'
#
#deps = {'spice-protocol' : '>= @0@'.format(spice_protocol_version),
#        'glib-2.0'       : glib_version_info,
#        'gio-2.0'        : glib_version_info,
#        'gobject-2.0'    : glib_version_info,
#        'pixman-1'       : pixman_version,
#        'openssl'        : '>= 1.0.0'}
#
#foreach dep, version : deps
#  spice_glib_deps += dependency(dep, version : version)
#endforeach
#
## mandatory dependencies, without specific version requirement
## TODO: specify minimum version for jpeg and zlib?
#deps = ['libjpeg', 'zlib', 'json-glib-1.0']
#if host_machine.system() == 'windows'
#  deps += 'gio-windows-2.0'
#else
#  deps += 'gio-unix-2.0'
#endif
#
#foreach dep : deps
#  spice_glib_deps += dependency(dep)
#endforeach
#
#deps = []
#if host_machine.system() == 'windows'
#  deps += ['ws2_32', 'gdi32', 'comctl32']
#endif
#
#foreach dep : deps
#  spice_glib_deps += compiler.find_library(dep)
#endforeach
#
##
## Non-mandatory/optional dependencies
##
#optional_deps = {'opus' : '>= 0.9.14'}
#foreach dep, version : optional_deps
#  d = dependency(dep, required : get_option(dep), version : version)
#  summary_info += {dep: d.found()}
#  if d.found()
#    spice_glib_deps += d
#    spice_gtk_config_data.set('HAVE_@0@'.format(dep.underscorify().to_upper()), '1')
#  endif
#endforeach
#
## gtk
#spice_gtk_has_gtk = false
#gtk_version_required = '3.22'
#d = dependency('gtk+-3.0', version : '>= @0@'.format(gtk_version_required),
#               required: get_option('gtk'))
#summary_info += {'gtk': d.found()}
#if d.found()
#  spice_gtk_deps += d
#  spice_gtk_deps += dependency('epoxy', required: spice_gtk_has_egl)
#  if host_machine.system() != 'windows'
#    d = dependency('x11', required: false)
#    if d.found()
#      spice_gtk_deps += d
#    endif
#    d = dependency('libva-x11', required: false)
#    if d.found()
#      spice_gtk_deps += d
#      spice_gtk_config_data.set('HAVE_LIBVA', '1')
#    endif
#  endif
#  spice_gtk_has_gtk = true
#endif
#
## wayland protocols
#spice_gtk_has_wayland_protocols = false
## Check if gtk is enabled and supports the wayland backend
#if host_machine.system() != 'windows' and spice_gtk_has_gtk and compiler.has_header('gtk-3.0/gdk/gdkwayland.h')
#  d = dependency('wayland-protocols', version: '>= 1.17', required: get_option('wayland-protocols'))
#  summary_info += {'wayland-protocols': d.found()}
#  if d.found()
#    spice_gtk_config_data.set('HAVE_WAYLAND_PROTOCOLS', '1')
#    dir_wp_base = d.get_variable(pkgconfig: 'pkgdatadir')
#    dep_scanner = dependency('wayland-scanner', native: true)
#    prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner'))
#
#    wayland_libs_version_required = '1.17.0'
#    spice_wayland_deps += dependency('wayland-server', version : '>= @0@'.format(wayland_libs_version_required))
#    spice_wayland_deps += dependency('wayland-cursor', version : '>= @0@'.format(wayland_libs_version_required))
#    spice_wayland_deps += dependency('wayland-client', version : '>= @0@'.format(wayland_libs_version_required))
#    spice_gtk_has_wayland_protocols = true
#  endif
#endif
#
## webdav
#spice_gtk_has_phodav = false
#phodav_dep = dependency('libphodav-3.0', required: false)
#if not phodav_dep.found()
#  phodav_dep = dependency('libphodav-2.0', required: get_option('webdav'))
#endif
#if phodav_dep.found()
#  spice_glib_deps += phodav_dep
#  if phodav_dep.name() == 'libphodav-3.0'
#    d = dependency('libsoup-3.0', version : '>= 3.0', required: get_option('webdav'))
#  else
#    d = dependency('libsoup-2.4', version : '>= 2.49.91', required: get_option('webdav'))
#  endif
#  if d.found()
#    spice_glib_deps += d
#    spice_gtk_config_data.set('USE_PHODAV', '1')
#    spice_gtk_has_phodav = true
#    if phodav_dep.version().version_compare('>= 2.5')
#      spice_gtk_config_data.set('HAVE_PHODAV_VIRTUAL', '1')
#    endif
#  endif
#endif
#summary_info += {'webdav': spice_gtk_has_phodav}
#
#gstreamer_version = '1.10'
#gstreamer_version_info = '>= @0@'.format(gstreamer_version)
#deps = ['gstreamer-1.0', 'gstreamer-base-1.0', 'gstreamer-app-1.0', 'gstreamer-audio-1.0', 'gstreamer-video-1.0']
#foreach dep : deps
#  spice_glib_deps += dependency(dep, version: gstreamer_version_info)
#endforeach
#
## builtin-mjpeg
#spice_gtk_has_builtin_mjpeg = false
#if get_option('builtin-mjpeg')
#  spice_gtk_config_data.set('HAVE_BUILTIN_MJPEG', '1')
#  spice_gtk_has_builtin_mjpeg = true
#endif
#summary_info += {'builtin-mjpeg': get_option('builtin-mjpeg')}
#
## usbredir
#spice_gtk_has_usbredir = false
#usbredir_version = '0.7.1'
#usbredir_version_info = '>= @0@'.format(usbredir_version)
#d1 = dependency('libusbredirparser-0.5', version: usbredir_version_info, required : get_option('usbredir'))
#d2 = dependency('libusbredirhost', version: usbredir_version_info, required : get_option('usbredir'))
#d3 = dependency('libusb-1.0', version : '>= 1.0.21', required : get_option('usbredir'))
#summary_info += {'usbredir': d1.found() and d2.found() and d3.found()}
#if d1.found() and d2.found() and d3.found()
#  if target_machine.endian() == 'little'
#    spice_glib_deps += [d1, d2, d3]
#    spice_gtk_config_data.set('USE_USBREDIR', '1')
#    spice_gtk_has_usbredir = true
#  else
#    warning('USB redirection disabled on big endian machine as ' +
#            'usbredir only support little endian')
#  endif
#endif
#
#d = dependency('libcap-ng', required : get_option('libcap-ng'))
#summary_info += {'libcap-ng': d.found()}
#if d.found()
#  spice_gtk_config_data.set('USE_LIBCAP_NG', '1')
#  spice_acl_deps += d
#endif
#
## polkit
#spice_gtk_has_polkit = false
#d = dependency('polkit-gobject-1', version : '>= 0.101', required : get_option('polkit'))
#summary_info += {'polkit': d.found()}
#if d.found()
#  spice_gtk_policy_dir = d.get_variable(pkgconfig: 'policydir')
#
#  # TODO:  With 'auto', we should just disable polkit support if this is missing.
#  if not compiler.has_function('acl_get_file')
#    acl_dep = compiler.find_library('acl')
#    if not compiler.has_function('acl_get_file', dependencies : acl_dep)
#      error('PolicyKit support requested, but some required packages are not available')
#    endif
#    spice_acl_deps += acl_dep
#  endif
#
#  spice_acl_deps += d
#  spice_acl_deps += dependency('gio-unix-2.0')
#  spice_gtk_config_data.set('USE_POLKIT', '1')
#  spice_gtk_has_polkit = true
#endif
#
#if spice_gtk_has_usbredir and not spice_gtk_has_polkit
#  warning('Building with usbredir support, but *not* building the usb acl helper')
#endif
#
## pie
#spice_gtk_has_pie = false
#if get_option('pie')
#  spice_gtk_has_pie = true
#endif
#summary_info += {'pie': spice_gtk_has_pie}
#
## usb-acl-helper-dir
#spice_gtk_usb_acl_helper_dir = get_option('usb-acl-helper-dir')
#if spice_gtk_usb_acl_helper_dir.strip() == ''
#  spice_gtk_usb_acl_helper_dir = spice_gtk_prefix / get_option('libexecdir')
#endif
#spice_gtk_config_data.set_quoted('ACL_HELPER_PATH', spice_gtk_usb_acl_helper_dir)
#summary_info += {'usb-acl-helper-dir': spice_gtk_usb_acl_helper_dir}
#
## usb-ids-path
#spice_gtk_usb_ids_path = get_option('usb-ids-path')
#if spice_gtk_usb_ids_path.strip() == ''
#  usbutils = dependency('usbutils', required : false)
#  if usbutils.found()
#    spice_gtk_usb_ids_path = usbutils.get_variable(pkgconfig: 'usbids')
#  endif
#endif
#summary_info += {'usb-ids-path': spice_gtk_usb_ids_path}
#
#if spice_gtk_usb_ids_path.strip() != ''
#  spice_gtk_config_data.set('WITH_USBIDS', '1')
#  spice_gtk_config_data.set_quoted('USB_IDS', spice_gtk_usb_ids_path)
#endif
#
## coroutine
#spice_gtk_coroutine = get_option('coroutine')
#if spice_gtk_coroutine == 'auto'
#  if host_machine.system() == 'windows'
#    spice_gtk_coroutine = 'winfiber'
#  else
#    spice_gtk_coroutine = 'ucontext'
#  endif
#endif
#
#if spice_gtk_coroutine == 'ucontext'
#  foreach f : ['makecontext', 'swapcontext', 'getcontext']
#    if not compiler.has_function(f)
#      error('Function missing:' + f)
#    endif
#  endforeach
#  spice_gtk_config_data.set('WITH_UCONTEXT', '1')
#  if host_machine.system() == 'darwin'
#    spice_gtk_config_data.set('_XOPEN_SOURCE', '1')
#  endif
#  endif
#
#if spice_gtk_coroutine == 'libucontext'
#  d = dependency('libucontext')
#  spice_glib_deps += d
#  spice_gtk_config_data.set('WITH_UCONTEXT', '1')
#  spice_gtk_config_data.set('HAVE_LIBUCONTEXT', '1')
#endif
#
if (coroutine STREQUAL "gthread")
    set(WITH_GTHREAD 1)
endif()
#
#if spice_gtk_coroutine == 'winfiber'
#  spice_gtk_config_data.set('WITH_WINFIBER', '1')
#endif
#summary_info += {'coroutine': spice_gtk_coroutine}
#
## introspection
#spice_gtk_has_introspection = false
#d = dependency('gobject-introspection-1.0', version : '>= 0.94', required : get_option('introspection'))
#if d.found()
#  spice_glib_deps += d
#  spice_gtk_has_introspection = true
#endif
#summary_info += {'introspection': spice_gtk_has_introspection}
#
## vala (depends on introspection)
#spice_gtk_has_vala = false
#d = dependency('vapigen', required : get_option('vapi'))
#if d.found()
#  if not spice_gtk_has_introspection
#    error('VAPI support requested without introspection')
#  endif
#  spice_gtk_has_vala = true
#endif
#summary_info += {'vapi': spice_gtk_has_vala}
#
## lz4
#d = dependency('liblz4', required : get_option('lz4'))
#if d.found()
#  spice_glib_deps += d
#  spice_gtk_config_data.set('USE_LZ4', '1')
#endif
#summary_info += {'lz4': d.found()}
#
## sasl
#d = dependency('libsasl2', required : get_option('sasl'))
#if d.found()
#  spice_glib_deps += d
#  spice_gtk_config_data.set('HAVE_SASL', '1')
#endif
#summary_info += {'sasl': d.found()}
#
## smartcard check
#d = dependency('libcacard', version : '>= 2.5.1', required : get_option('smartcard'))
#if d.found()
#  spice_glib_deps += d
#  spice_gtk_config_data.set('USE_SMARTCARD', '1')
#endif
#summary_info += {'smartcard': d.found()}
#
## valgrind
#if get_option('valgrind')
#  if spice_gtk_config_data.get('HAVE_VALGRIND_VALGRIND_H', '0') != '1'
#    error('Valgrind requested but headers not found')
#  endif
#  spice_gtk_config_data.set('HAVE_VALGRIND', '1')
#endif
#summary_info += {'valgrind': get_option('valgrind')}
##
## global C defines
##
#glib_encoded_version = 'GLIB_VERSION_@0@'.format(glib_version.underscorify())
#spice_gtk_global_cflags += ['-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_encoded_version),
#                            '-DGLIB_VERSION_MAX_ALLOWED=@0@'.format(glib_encoded_version)]
#
#if spice_gtk_has_gtk
#  gtk_encoded_version='GDK_VERSION_@0@'.format(gtk_version_required.underscorify())
#  spice_gtk_global_cflags += ['-DGDK_VERSION_MIN_REQUIRED=@0@'.format(gtk_encoded_version),
#                              '-DGDK_VERSION_MAX_ALLOWED=@0@'.format(gtk_encoded_version)]
#endif
#
## Workaround gtk+ exposing Objective C: https://gitlab.gnome.org/GNOME/gtk/issues/1737
#if host_machine.system() == 'darwin'
#  spice_gtk_global_cflags += ['-ObjC']
#endif
#
#add_project_arguments(compiler.get_supported_arguments(spice_gtk_global_cflags),
#                      language : 'c')
#
##
## write config.h
##
#proj_version = meson.project_version()
#proj_name = meson.project_name()
#config_data = {'VERSION' : proj_version,
#               'PACKAGE_VERSION' : proj_version,
#               'GETTEXT_PACKAGE' : proj_name,
#               'LOCALE_DIR' : spice_gtk_localedir,
#               'PACKAGE_STRING' : '@0@ @1@'.format(proj_name, proj_version),
#               'PACKAGE_BUGREPORT' : 'spice-devel@lists.freedesktop.org'}
#foreach key, value : config_data
#  spice_gtk_config_data.set_quoted(key, value)
#endforeach

add_library(spice-gtk-macro-interface INTERFACE)
target_compile_definitions(spice-gtk-macro-interface
        INTERFACE
        VERSION="0.0.1"
        PACKAGE_VERSION="0.0.1"
        GETTEXT_PACKAGE="spice-gtk"
        LOCALE_DIR="/usr/share/locale"
        PACKAGE_STRING="spice-gtk-0.0.1"
        PACKAGE_BUGREPORT="spice-devel@lists.freedesktop.org"
#        ${spice_gtk_global_flags}
        SPICE_COMPILATION
        HAVE_CONFIG_H
    )

#
#configure_file(output : 'config.h',
#               configuration : spice_gtk_config_data)
#
##
## Subdirectories
##
#subdir('src')
#subdir('tools')
#subdir('tests')
#if build_machine.system() == 'windows'
#  message('Disabling gtk-doc while building on Windows')
#else
#  d = find_program('gtkdoc-scan', required : get_option('gtk_doc'))
#  if d.found()
#    subdir('doc')
#  endif
#  summary_info += {'gtk_doc': d.found()}
#endif
#subdir('data')
#subdir('man')
#subdir('po')
#subdir('vapi')
#
##
## write spice-client-glib.pc
##
#pkgconfig = import('pkgconfig')
#pkgconfig.generate(spice_client_glib_lib,
#                   description : 'SPICE Client GLib 2.0 library',
#                   subdirs : 'spice-client-glib-2.0',
#                   requires : ['spice-protocol', 'glib-2.0', 'gobject-2.0', 'gio-2.0'],
#                   variables : 'exec_prefix=${prefix}')
#
##
## write spice-client-gtk.pc
##
#if spice_gtk_has_gtk
#  pkgconfig.generate(spice_client_gtk_lib,
#                     description : 'SPICE Client Gtk 3.0 library',
#                     subdirs : 'spice-client-gtk-3.0',
#                     requires : ['spice-client-glib-2.0', 'gtk+-3.0', 'glib-2.0', 'gobject-2.0'],
#                     variables : 'exec_prefix=${prefix}')
#endif
#
#summary(summary_info, bool_yn: true)
configure_file(config.h.cmake config.h @ONLY)
add_subdirectory(3rdparty)
add_subdirectory(src)
add_subdirectory(tools)
# add_subdirectory(example)
